package com.bloody.android.Characters;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Random;

import com.bloody.android.BloodyCrusadeGame;
import com.bloody.android.Map.Map;

import android.os.Bundle;
import android.util.Log;

public abstract class Character implements Serializable {
	
	public final static int MAX_LIFE = 200;
	
	private static int freeID1=0;
	private static int freeID2=0;
	private String ID;
	private int move;
	private int attack;
	private int defense;
	private int life;
	private int player;
	private int posx;
	private int posy;
	private int [] attackRange;
	private Map map;
	private boolean alive;
	private boolean hasPlayed;
	private boolean hasMoved;
	private SpecialAbility ability;
	private Random r = new Random();
	
	public Character(int player, int move, int attack, int defense){//, int life){
		if(player==1) {
			this.ID=""+player+freeID1;
			freeID1++;
		}
		else {
			this.ID=""+player+freeID2;
			freeID2++;
		}
		
		Log.d("DEBUG", ID);
		this.player = player;
		//this.type = type;
		this.life = MAX_LIFE;//life;
		this.move= move;
		this.attack = 30 + attack;
		this.defense = defense;
		this.alive = true;
		this.hasPlayed = false;
		this.hasMoved = false;
		//this.ability = ability;
	}
	
	public int getAttack() {
		return attack;
	}

	public int getDefense() {
		return defense;
	}

	public Map getMap(){
		return map;
	}

	public boolean getHasMoved() {
		return hasMoved;
	}

	public void setHasMoved(boolean hasMoved) {
		this.hasMoved = hasMoved;
	}

	public void setAttackRange(int[] attackRange) {
		this.attackRange = attackRange;
	}
	
	public void addDefense(int def){
		this.defense+=def;
	}
	
	public void addAttack(int att){
		attack+=att;
	}

	public void setMap(Map map){
		this.map = map;
	}
	
	public void showMapAbility(){
		map.showRange(ability.getRange(), posx, posy, player);
		Log.d("DEBUG", "out");
	}

	public int getLife() {
		return life;
	}
	
	public Bundle specialAbility(BloodyCrusadeGame bcg, int level){
		return ability.effect(bcg, level);
	}
	
	public void setLife(int life) {
		if(life<=0)
		{
			this.life=0;
			dead();
		}
		else if(life>=MAX_LIFE)
			this.life=MAX_LIFE;
		else
			this.life = life;
	}

	public boolean getHasPlayed() {
		return hasPlayed;
	}

	public void setHasPlayed(boolean hasPlayed) {
		this.hasPlayed = hasPlayed;
	}

	public void showMove(){
		map.showMove(posx, posy, move);
	}
	
	public void showAttack(){
		map.showRange(attackRange, posx, posy, player);
	}
	
	public void setPosition(int posx, int posy){
		this.posx= posx;
		this.posy = posy;
	}
	
	public int getPosx() {
		return posx;
	}

	public int getPosy() {
		return posy;
	}

	public int getMove() {
		return move;
	}
	
	public int getPlayer(){
		return player;
	}
	
	public void hurt(int dommage){
		int lifeLoose = Math.max(5, dommage - defense) ;
		setLife(life-lifeLoose);
	}
	
	public boolean isAlive() {
		return alive;
	}

	private void dead(){
		map.removeCharacter(this.posy, this.posx);
		alive = false;
	}
	
	public void attack(Character ch, boolean heavyAttack){
		int dommage = attack;
		if(!heavyAttack)
				dommage/=2;
		ch.hurt(dommage+r.nextInt(11)-5);
	}

	public void changePosition(int newposx,int newposy){
		map.removeCharacter(this.posy, this.posx);
		map.addCharacter(newposy, newposx, this);
		this.posx = newposx;
		this.posy = newposy;
	}

	public String getID() {
		return ID;
	}
	
	public void setAbility(SpecialAbility ability){
		this.ability = ability;
		ability.setCharacter(this);
	}

	public static void reset()
	{
		freeID1=0;
		freeID2=0;
	}
	
	@Override
	public String toString()
	{
		return ID+" "+life+" "+posx+" "+posy;
	}
	
	public void update(ArrayList<String> datas)
	{
		setLife(Integer.parseInt(datas.get(1)));
		this.changePosition(Integer.parseInt(datas.get(2)), Integer.parseInt(datas.get(3)));
	}
	
	public String getSpecAbName()
	{
		return ability.getName();
	}
}
